home *** CD-ROM | disk | FTP | other *** search
- /* General Mail Utilities
- * culled from other files to reduce unnecessary cross references.
- * This material is believed to be in the public domain.
- */
- #include <stdio.h>
- #include <io.h>
- #include <fcntl.h>
- #include <ctype.h>
- #include "global.h"
- #include "config.h"
- #include "socket.h"
- #include "mailutil.h"
- #include "smtp.h"
- #include "files.h"
-
-
- extern FILE *subdir_fopen __ARGS((char *name, char *mode));
- extern char *nntp_name_expansion __ARGS((char *name));
-
- /* Jan 92 Bill Simpson
- * The following routines were combined from smtpserv.c,
- * pop3cli.c and nntpcli.c
- */
-
- #ifdef POP3CLIENT
-
- /* Receive message from socket, copying to file.
- * Returns number of lines received, -1 indicates error
- */
- int
- recvmail(s,buf,len,fp,trace)
- int s; /* Socket index */
- char *buf; /* Line buffer */
- unsigned len; /* Length of buffer */
- FILE *fp; /* File to copy into */
- int trace; /* to trace or not to trace */
- {
- int lines = 0;
-
- while (recvline(s,buf,len) != -1) {
- register char *p = buf;
-
- if (trace >= 4)
- log(s,"<==%s", buf);
-
- /* check for end of message . or escaped .. */
- if (*p == '.') {
- if (*++p == '\n') {
- if (trace >= 3)
- log(s,"received %d lines", lines);
- return lines;
- } else if ( *p != '.' ) {
- p--;
- }
- } else if (strncmp(p,"From ",5) == 0) {
- /* for UNIX mail compatiblity */
- (void) putc('>',fp);
- }
- /* Append to data file */
- fputs(p,fp);
- ++lines;
- }
- if ( trace >= 1 )
- log(s,"receive error after %d lines", lines);
- return -1;
- }
- #endif
-
- #if (defined(POP2CLIENT) || defined(POP3CLIENT))
-
- /* Copy from the work file into the mailbox.
- * -1 indicates error
- */
- int
- copymail(buf,len,wfp)
- char *buf; /* Line buffer */
- unsigned len; /* Length of buffer */
- FILE *wfp; /* File to copy from */
- {
- FILE *mfp = NULLFILE;
- char *cp;
- int first = 0;
- struct list *cclist = NULLLIST;
- char from[256], to[256];
-
-
- rewind (wfp);
- from[0] = 0;
- to[0] = 0;
- while(fgets(buf,len,wfp) != NULLCHAR){
- pwait(NULL); /* give other processes time in long copy */
- if (!first) {
- mfp = tmpfile();
- if (!mfp)
- return -1;
- putc ('>', mfp);
- first = 1;
- } else if (!strncmp(buf, "From ", 5)) {
- addlist(&cclist,to,0,to);
- fseek(mfp,0L,0);
- pwait (NULL); /* just to be nice to others */
- if (to[0] && from[0])
- queuejob(mfp,Hostname,cclist,from);
- del_list (cclist);
- cclist = NULLLIST;
- fclose (mfp);
- from[0] = 0;
- to[0] = 0;
- mfp = tmpfile();
- if (!mfp)
- return -1;
- putc ('>', mfp);
- }
- fputs(buf,mfp);
-
-
- if (!from[0] && !strncmp ("From: ", buf, 6)) {
- rip (buf);
- strcpy (from, &buf[6]);
- if ((cp = strchr (from, ' ')) != 0)
- *cp = 0;
- }
- if (!to[0] && !strncmp ("To: ", buf, 4)) {
- rip (buf);
- strcpy (to, &buf[4]);
- if ((cp = strchr (from, ' ')) != 0)
- *cp = 0;
- }
- }
- addlist(&cclist,to,0,to);
- fseek(mfp,0L,0);
- pwait (NULL); /* just to be nice to others */
- if (to[0] && from[0])
- queuejob(mfp,Hostname,cclist,from);
- fclose(mfp);
-
- return 0;
- }
- #endif
-
-
- /* Jan 92 Bill Simpson
- * The following routines were extracted from smtpserv.c
- * and smtpcli.c, since they are used from several places.
- */
-
- /* create mail lockfile */
- int
- mlock(dir,id)
- char *dir,*id;
- {
- char lockname[FILE_PATH_SIZE];
- int fd;
- FILE *fp;
- #ifdef notdef
- /* This is NOT a good idea ! This prevents all mailfiles in subdirs
- * to be accessed; thus no nntp access etc... - WG7J
- */
-
- #ifdef MSDOS
- if(strlen(id) > 8) { /* truncate long filenames */
- id[8] = '\0';
- if(id[7] == '/')
- id[7] = '\0';
- }
- #endif
- #endif
-
- /* Try to create the lock file in an atomic operation */
- sprintf(lockname,"%s/%s",dir,id);
- nntp_name_expansion (lockname);
- strcat(lockname,".lck");
- #ifdef AMIGA
- /* don't ask, really, just don't ask... I'd do file locking on
- * an Amiga much more differently than this.
- */
- if(access(lockname, 0) == 0)
- return -1;
- #endif
- /* this is to create any needed directories for nntp-style areas */
- fp = subdir_fopen (lockname, "w");
- if (fp) {
- fclose (fp);
- unlink (lockname);
- }
- #ifndef TNOS_68K
- if((fd = open(lockname, O_WRONLY|O_EXCL|O_CREAT,0600)) == -1)
- #else
- if((fd = creat(lockname, S_ISHARE)) == -1)
- #endif
- return -1;
- close(fd);
- return 0;
- }
-
-
- /* remove mail lockfile */
- int
- rmlock(dir,id)
- char *dir,*id;
- {
- char lockname[FILE_PATH_SIZE];
-
- #ifdef notdef /* See mlock() above - WG7J */
- #ifdef MSDOS
- if(strlen(id) > 8) { /* truncate long filenames */
- id[8] = '\0';
- if(id[7] == '/')
- id[7] = '\0';
- }
- #endif
- #endif
-
- sprintf(lockname,"%s/%s.lck",dir,id);
- return(unlink(lockname));
- }
-
-
- /* Given a string of the form <user@host>, extract the part inside the
- * angle brackets and return a pointer to it.
- */
- char *
- getname(cp)
- register char *cp;
- {
- register char *cp1;
-
- if ((cp = strchr(cp,'<')) == NULLCHAR)
- return NULLCHAR;
- cp++; /* cp -> first char of name */
- if ((cp1 = strchr(cp,'>')) == NULLCHAR)
- return NULLCHAR;
- *cp1 = '\0';
- return cp;
- }
-
-
- /* Jan 92 Bill Simpson
- * The following routines were extracted from mailbox.c,
- * since they are used from several places.
- */
-
-
- /* Parse a string in the "Text: Text <user@host>" or "Text: user@host (Text)"
- * formats for the address user@host.
- */
- char *
- getaddress(string,cont)
- char *string;
- int cont; /* true if string is a continued header line */
- {
- char *cp, *ap = NULLCHAR;
- int par = 0;
-
- if((cp = getname(string)) != NULLCHAR) /* Look for <> style address */
- return cp;
-
- cp = string;
- if(!cont)
- if((cp = strchr(string,':')) == NULLCHAR) /* Skip the token */
- return NULLCHAR;
- else
- ++cp;
- for(; *cp != '\0'; ++cp) {
- if(par && *cp == ')') {
- --par;
- continue;
- }
- if(*cp == '(') /* Ignore text within parenthesis */
- ++par;
- if(par)
- continue;
- if(*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == ',') {
- if(ap != NULLCHAR)
- break;
- continue;
- }
- if(ap == NULLCHAR)
- ap = cp;
- }
- *cp = '\0';
- return ap;
- }
-
-
- char *Hdrs[] = {
- "Approved: ",
- "From: ",
- "To: ",
- "Date: ",
- "Message-Id: ",
- "Subject: ",
- "Received: ",
- "Sender: ",
- "Reply-To: ",
- "Status: ",
- "X-BBS-Msg-Type: ",
- "X-Forwarded-To: ",
- "Cc: ",
- "Return-Receipt-To: ",
- "Apparently-To: ",
- "Errors-To: ",
- "Organization: ",
- "Newsgroups: ",
- "Path: ",
- "X-BBS-Hold: ",
- "X-Mail-Group: ",
- NULLCHAR
- };
-
-
- /* return the header type */
- int
- htype(s)
- char *s;
- {
- register char *p;
- register int i;
-
- p = s;
- /* check to see if there is a ':' before and white space */
- while (*p != '\0' && *p != ' ' && *p != ':')
- p++;
- if (*p != ':')
- return NOHEADER;
-
- for (i = 0; Hdrs[i] != NULLCHAR; i++) {
- if (strnicmp(Hdrs[i],s,strlen(Hdrs[i])) == 0)
- return i;
- }
- return UNKNOWN;
- }
-
-
- /* Read the rewrite file for lines where the first word is a regular
- * expression and the second word are rewriting rules. The special
- * character '$' followed by a digit denotes the string that matched
- * a '*' character. The '*' characters are numbered from 1 to 9.
- * Example: the line "*@*.* $2@$1.ampr.org" would rewrite the address
- * "foo@bar.xxx" to "bar@foo.ampr.org".
- * $H is replaced by our hostname, and $$ is an escaped $ character.
- * If the third word on the line has an 'r' character in it, the function
- * will recurse with the new address.
- */
- char *
- rewrite_address(addr)
- register char *addr;
- {
- char *argv[10], buf[PLINELEN];
- register char *cp, *cp2, *retstr;
- register int cnt;
- register FILE *fp;
-
- if ((fp = fopen(Rewritefile,READ_TEXT)) == NULLFILE)
- return NULLCHAR;
-
- memset((char *)argv,0,10*sizeof(char *));
- while(fgets(buf,sizeof(buf),fp) != NULLCHAR) {
- pwait (NULL);
- if(*buf == '#') /* skip commented lines */
- continue;
- if((cp = strpbrk(buf," \t")) == NULLCHAR) /* get the first word */
- continue;
- *cp = '\0';
- if((cp2 = strchr(buf,'\t')) != NULLCHAR){
- *cp = ' ';
- cp = cp2;
- *cp = '\0';
- }
- if(!wildmat(addr,buf,argv))
- continue; /* no match */
- rip(++cp);
- cp2 = retstr = (char *) callocw(1,PLINELEN);
- while(*cp != '\0' && *cp != ' ' && *cp != '\t')
- if(*cp == '$') {
- if(isdigit(*(++cp)))
- if(argv[*cp - '0'-1] != '\0')
- strcat(cp2,argv[*cp - '0'-1]);
- if(*cp == 'h' || *cp == 'H') /* Our hostname */
- strcat(cp2,Hostname);
- if(*cp == '$') /* Escaped $ character */
- strcat(cp2,"$");
- cp2 = retstr + strlen(retstr);
- cp++;
- }
- else
- *cp2++ = *cp++;
- for(cnt=0; argv[cnt] != NULLCHAR; ++cnt)
- free(argv[cnt]);
- fclose(fp);
- /* If there remains an 'r' character on the line, repeat
- * everything by recursing.
- */
- if(strchr(cp,'r') != NULLCHAR || strchr(cp,'R') != NULLCHAR) {
- if((cp2 = rewrite_address(retstr)) != NULLCHAR) {
- free(retstr);
- return cp2;
- }
- }
- return retstr;
- }
- fclose(fp);
- return NULLCHAR;
- }
-
-